package tech.runchen.gz5055.oms.modules.system.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.factory.annotation.Autowired;
import tech.runchen.gz5055.oms.common.enums.OrderStatus;
import tech.runchen.gz5055.oms.common.enums.ReturnOrderStatus;
import tech.runchen.gz5055.oms.common.enums.UserType;
import tech.runchen.gz5055.oms.common.utils.MapUtils;
import tech.runchen.gz5055.oms.common.utils.PageInfo;
import tech.runchen.gz5055.oms.common.utils.Query;
import tech.runchen.gz5055.oms.common.websocket.WebSocketServer;
import tech.runchen.gz5055.oms.modules.system.entity.NoticeEntity;
import tech.runchen.gz5055.oms.modules.system.entity.OrderEntity;
import tech.runchen.gz5055.oms.modules.system.entity.ReturnOrderEntity;
import tech.runchen.gz5055.oms.modules.system.entity.UserNoticeEntity;
import tech.runchen.gz5055.oms.modules.system.mapper.NoticeMapper;
import tech.runchen.gz5055.oms.modules.system.service.INoticeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import tech.runchen.gz5055.oms.modules.system.service.IUserNoticeService;
import tech.runchen.gz5055.oms.modules.system.service.IUserService;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 消息通知表 服务实现类
 * </p>
 *
 * @author zzj
 * @since 2023-11-13
 */
@Service
public class NoticeServiceImpl extends ServiceImpl<NoticeMapper, NoticeEntity> implements INoticeService {

    @Autowired
    private IUserNoticeService userNoticeService;
    @Autowired
    private IUserService userService;
    @Autowired
    private WebSocketServer webSocketServer;

    @Override
    public PageInfo queryPage(Map<String, Object> params) {

        Object userType = params.get("userType");
        Object userId = params.get("userId");
        String title = (String) params.get("title");
        String content = (String) params.get("content");

        List<Long> noticeIdList = userNoticeService.queryNoticeIdList((Long) userId);
        noticeIdList.add(-1L);

        IPage<NoticeEntity> page = this.page(
                new Query<NoticeEntity>().getPage(params),
                new QueryWrapper<NoticeEntity>()
                        .in(!UserType.ADMIN.getCode().equals(userType), "id", noticeIdList)
                        .like(Objects.nonNull(title), "title", title)
                        .like(Objects.nonNull(content), "content", content)
                        .orderByDesc("id")
        );
        return new PageInfo(page);
    }

    @Override
    public List<NoticeEntity> querySelect(Map<String, Object> params) {

        Object userType = params.get("userType");
        Object userId = params.get("userId");
        String title = (String) params.get("title");
        String content = (String) params.get("content");

        List<Long> noticeIdList = userNoticeService.queryNoticeIdList((Long) userId);
        noticeIdList.add(-1L);

        List<NoticeEntity> list = this.list(
                new QueryWrapper<NoticeEntity>()
                        .in(!UserType.ADMIN.getCode().equals(userType), "id", noticeIdList)
                        .like(Objects.nonNull(title), "title", title)
                        .like(Objects.nonNull(content), "content", content)
                        .orderByDesc("id")
        );

        return list;
    }

    @Override
    public boolean saveNotice(NoticeEntity notice) {
        return this.save(notice);
    }

    @Override
    public boolean updateNotice(NoticeEntity notice) {
        return this.updateById(notice);
    }

    @Override
    public void createOrderNotice(OrderEntity order, OrderStatus orderStatus) {
        String title = "";
        String content = "";
        List<Long> userIds = new ArrayList<>();
        switch (orderStatus) {
            case WAIT:
                title = "新订单";
                content = String.format("收到新订单：%s，目的地：%s", order.getOrderNumber(), order.getDeliveryAddress());
                userIds.addAll(userService.queryUserIdList(UserType.SPD.getCode()));
                break;
            case SHIPPED:
                title = "订单已发出";
                content = String.format("您的订单：%s已发出，正在前往目的地：%s", order.getOrderNumber(), order.getDeliveryAddress());
                userIds.add(order.getOrderUserId());
                break;
            case DONE:
                title = "订单已完成";
                content = String.format("您的订单：%s已完成，请确认耗材是否齐全，如有遗漏请联系SPD。", order.getOrderNumber());
                userIds.add(order.getOrderUserId());
                break;
            case CANCEL:
                title = "订单已取消";
                content = String.format("目的地为%s的订单%s已取消，如已装货请取出", order.getDeliveryAddress(), order.getOrderNumber());
                userIds.add(order.getOrderUserId());
                userIds.addAll(userService.queryUserIdList(UserType.SPD.getCode()));
                break;
            case TIMEOUT_SHIPPED:
                title = "订单超时未配送";
                content = String.format("目的地为%s的订单%s长时间未发货，请确认订单状态", order.getDeliveryAddress(), order.getOrderNumber());
                userIds.add(order.getOrderUserId());
                userIds.addAll(userService.queryUserIdList(UserType.SPD.getCode()));
                break;
            case TIMEOUT_DONE:
                title = "订单配送异常";
                content = String.format("目的地为%s的订单%s长时间未送达，请确认是否配送异常", order.getDeliveryAddress(), order.getOrderNumber());
                userIds.add(order.getOrderUserId());
                userIds.addAll(userService.queryUserIdList(UserType.SPD.getCode()));
                break;
            default:
                break;
        }
        // 通知保存
        NoticeEntity notice = new NoticeEntity();
        notice.setTitle(title);
        notice.setContent(content);
        this.saveNotice(notice);
        // 建立用户通知关系
        userNoticeService.saveOrUpdate(notice.getId(), userIds);
        // 发送通知
        userIds.forEach((uid) -> {
            webSocketServer.sendToUid(uid.toString(), JSONObject.toJSONString(notice));
        });
    }

    @Override
    public void createReturnOrderNotice(ReturnOrderEntity returnOrder, ReturnOrderStatus returnOrderStatus) {
        String title = "";
        String content = "";
        List<Long> userIds = new ArrayList<>();
        switch (returnOrderStatus) {
            case WAIT:
                title = "订单退货通知";
                content = String.format("收到退货订单：%s，取货地点：%s", returnOrder.getReturnOrderNumber(), returnOrder.getPickupAddress());
                userIds.addAll(userService.queryUserIdList(UserType.SPD.getCode()));
                break;
            case SHIPPED:
                title = "退货订单已装车";
                content = String.format("退货订单：%s已装车，正在前往SPD", returnOrder.getReturnOrderNumber());
                userIds.addAll(userService.queryUserIdList(UserType.SPD.getCode()));
                break;
            case CHECKED:
                title = "退货核验完成";
                content = String.format("您的退货单：%s已核验完成，如有问题请联系SPD。", returnOrder.getReturnOrderNumber());
                userIds.add(returnOrder.getInitiateUserId());
                break;
            case CANCEL:
                title = "取消退货通知";
                content = String.format("取货地点为%s的退货单%s已取消。", returnOrder.getPickupAddress(), returnOrder.getReturnOrderNumber());
                userIds.add(returnOrder.getInitiateUserId());
                userIds.addAll(userService.queryUserIdList(UserType.SPD.getCode()));
                break;
            case TIMEOUT_CHECKED:
                title = "退货单超时未核验";
                content = String.format("取货地点为%s的退货单%s长时间未核验，请确认订单状态", returnOrder.getPickupAddress(), returnOrder.getReturnOrderNumber());
                userIds.add(returnOrder.getInitiateUserId());
                userIds.addAll(userService.queryUserIdList(UserType.SPD.getCode()));
                break;
            default:
                break;
        }
        // 通知保存
        NoticeEntity notice = new NoticeEntity();
        notice.setTitle(title);
        notice.setContent(content);
        this.saveNotice(notice);
        // 建立用户通知关系
        userNoticeService.saveOrUpdate(notice.getId(), userIds);
        // 发送通知
        userIds.forEach((uid) -> {
            webSocketServer.sendToUid(uid.toString(), JSONObject.toJSONString(notice));
        });
    }

    @Override
    public void deleteNotice(Long userId, Long noticeId) {
        userNoticeService.remove(new QueryWrapper<UserNoticeEntity>().eq("user_id", userId).eq("notice_id", noticeId));
    }
}
